using Microsoft.EntityFrameworkCore;

namespace RAG.Application.Commands;

/// <summary>
/// 分页工具类
/// </summary>
public static class PaginationHelper
{
    /// <summary>
    /// 分页查询
    /// </summary>
    /// <typeparam name="T">实体类型</typeparam>
    /// <param name="query">查询表达式</param>
    /// <param name="page">页码（从1开始）</param>
    /// <param name="size">每页大小</param>
    /// <returns>分页结果</returns>
    public static async Task<PagedResult<T>> ToPagedResultAsync<T>(
        this IQueryable<T> query,
        int page,
        int size) where T : class
    {
        // 参数验证
        page = Math.Max(1, page);
        size = Math.Max(1, Math.Min(size, 1000)); // 限制最大页大小为1000

        // 计算总数
        var total = await query.CountAsync();

        // 分页查询
        var items = await query
            .Skip((page - 1) * size)
            .Take(size)
            .ToListAsync();

        return PagedResult<T>.Create(items, total, page, size);
    }

    /// <summary>
    /// 分页查询（带搜索）
    /// </summary>
    /// <typeparam name="T">实体类型</typeparam>
    /// <param name="query">查询表达式</param>
    /// <param name="page">页码（从1开始）</param>
    /// <param name="size">每页大小</param>
    /// <param name="searchPredicate">搜索条件</param>
    /// <param name="searchTerm">搜索关键词</param>
    /// <returns>分页结果</returns>
    public static async Task<PagedResult<T>> ToPagedResultAsync<T>(
        this IQueryable<T> query,
        int page,
        int size,
        Func<IQueryable<T>, string, IQueryable<T>> searchPredicate,
        string? searchTerm) where T : class
    {
        // 参数验证
        page = Math.Max(1, page);
        size = Math.Max(1, Math.Min(size, 1000));

        // 应用搜索条件
        if (!string.IsNullOrEmpty(searchTerm) && searchPredicate != null)
        {
            query = searchPredicate(query, searchTerm);
        }

        // 计算总数
        var total = await query.CountAsync();

        // 分页查询
        var items = await query
            .Skip((page - 1) * size)
            .Take(size)
            .ToListAsync();

        return PagedResult<T>.Create(items, total, page, size);
    }

    /// <summary>
    /// 分页查询（带排序）
    /// </summary>
    /// <typeparam name="T">实体类型</typeparam>
    /// <param name="query">查询表达式</param>
    /// <param name="page">页码（从1开始）</param>
    /// <param name="size">每页大小</param>
    /// <param name="orderBy">排序表达式</param>
    /// <param name="isDescending">是否降序</param>
    /// <returns>分页结果</returns>
    public static async Task<PagedResult<T>> ToPagedResultAsync<T>(
        this IQueryable<T> query,
        int page,
        int size,
        Func<IQueryable<T>, IQueryable<T>> orderBy,
        bool isDescending = false) where T : class
    {
        // 参数验证
        page = Math.Max(1, page);
        size = Math.Max(1, Math.Min(size, 1000));

        // 应用排序
        if (orderBy != null)
        {
            query = orderBy(query);
        }

        // 计算总数
        var total = await query.CountAsync();

        // 分页查询
        var items = await query
            .Skip((page - 1) * size)
            .Take(size)
            .ToListAsync();

        return PagedResult<T>.Create(items, total, page, size);
    }

    /// <summary>
    /// 分页查询（带搜索和排序）
    /// </summary>
    /// <typeparam name="T">实体类型</typeparam>
    /// <param name="query">查询表达式</param>
    /// <param name="page">页码（从1开始）</param>
    /// <param name="size">每页大小</param>
    /// <param name="searchPredicate">搜索条件</param>
    /// <param name="searchTerm">搜索关键词</param>
    /// <param name="orderBy">排序表达式</param>
    /// <param name="isDescending">是否降序</param>
    /// <returns>分页结果</returns>
    public static async Task<PagedResult<T>> ToPagedResultAsync<T>(
        this IQueryable<T> query,
        int page,
        int size,
        Func<IQueryable<T>, string, IQueryable<T>>? searchPredicate = null,
        string? searchTerm = null,
        Func<IQueryable<T>, IQueryable<T>>? orderBy = null,
        bool isDescending = false) where T : class
    {
        // 参数验证
        page = Math.Max(1, page);
        size = Math.Max(1, Math.Min(size, 1000));

        // 应用搜索条件
        if (!string.IsNullOrEmpty(searchTerm) && searchPredicate != null)
        {
            query = searchPredicate(query, searchTerm);
        }

        // 应用排序
        if (orderBy != null)
        {
            query = orderBy(query);
        }

        // 计算总数
        var total = await query.CountAsync();

        // 分页查询
        var items = await query
            .Skip((page - 1) * size)
            .Take(size)
            .ToListAsync();

        return PagedResult<T>.Create(items, total, page, size);
    }
} 